package com.xy.webadmin.app.service;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.xy.webadmin.app.constant.MqttConstants;
import com.xy.webadmin.app.model.MqttBrokerConfig;
import com.xy.webadmin.app.util.MqttApiUtil;
import com.xy.webadmin.app.vo.MqttDeviceStatusVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * MQTT控制台HTTP API客户端服务
 * 仅支持EMQX服务商
 *
 * @author xiaoyue
 * @date 2025-07-03
 */
@Slf4j
@Service
public class MqttApiService {

    @Autowired
    private MqttBrokerConfigService mqttBrokerConfigService;
    
    /**
     * 获取设备在线状态统计信息
     * 使用Redis缓存减少API调用频率
     * 
     * 注意：确保方法永远不返回null，而是返回空对象
     *
     * @param configId MQTT配置ID
     * @return 设备状态信息，永远不为null
     */
    @Cacheable(value = MqttConstants.Cache.DEVICE_STATUS, key = "#configId", cacheManager = "mqttCacheManager")
    public MqttDeviceStatusVo getDeviceStatusSummary(Long configId) {
        log.info("获取设备状态信息::{}",configId);
        MqttDeviceStatusVo result = getDeviceStatusSummaryNoCache(configId);
        // 确保永远不返回null
        if (result == null) {
            log.warn("获取到null结果，创建空对象替代，configId: {}", configId);
            return createEmptyStatus(null);
        }
        return result;
    }
    
    /**
     * 获取设备在线状态统计信息（不使用缓存）
     * 此方法用于强制刷新缓存或在缓存刷新任务中使用
     *
     * @param configId MQTT配置ID
     * @return 设备状态信息
     */
    public MqttDeviceStatusVo getDeviceStatusSummaryNoCache(Long configId) {
        log.info("获取设备状态信息(无缓存)::{}",configId);
        try {
            MqttBrokerConfig config = mqttBrokerConfigService.getById(configId);
            if (config == null) {
                log.error("MQTT配置不存在，configId: {}", configId);
                return createEmptyStatus(null);
            }
            
            if (config.getBrokerUrl() == null) {
                log.error("MQTT Broker URL为空，configId: {}", configId);
                return createEmptyStatus(config);
            }
            // 由于目前HTTP API功能仅支持EMQX，直接调用其状态获取方法。
            // 如果未来需要支持其他服务商，这里需要添加服务商类型的判断逻辑。
            return getEmqxDeviceStatus(config);
        } catch (Exception e) {
            log.error("获取MQTT设备状态失败，configId: {}, error: {}", configId, e.getMessage(), e);
            return createEmptyStatus(null);
        }
    }
    
    /**
     * 根据MQTT Broker配置获取按公司分组的设备状态汇总
     *
     * @param companyId 公司ID
     * @return 设备状态汇总
     */
    @Cacheable(value = MqttConstants.Cache.DEVICE_STATUS_BY_COMPANY, key = "#companyId", cacheManager = "mqttCacheManager")
    public Map<String, Object> getDeviceStatusByCompany(Long companyId) {
        try {
            // 获取公司下所有MQTT配置
            MqttBrokerConfig filter = new MqttBrokerConfig();
            filter.setCompanyId(companyId);
            List<MqttBrokerConfig> configList = mqttBrokerConfigService.getMqttBrokerConfigList(filter, null);
            // 汇总所有配置下的设备状态
            int totalDevices = 0;
            int onlineDevices = 0;
            int offlineDevices = 0;
            
            for (MqttBrokerConfig config : configList) {
                try {
                    MqttDeviceStatusVo status = getDeviceStatusSummary(config.getId());
                    if (status != null) {
                        totalDevices += status.getTotalDevices();
                        onlineDevices += status.getOnlineDevices();
                        offlineDevices += status.getOfflineDevices();
                    }
                } catch (Exception e) {
                    log.error("获取配置ID: {}的设备状态失败", config.getId(), e);
                }
            }
            
            Map<String, Object> result = new HashMap<>();
            result.put(MqttConstants.Monitoring.StatusFields.TOTAL_DEVICES, totalDevices);
            result.put(MqttConstants.Monitoring.StatusFields.ONLINE_DEVICES, onlineDevices);
            result.put(MqttConstants.Monitoring.StatusFields.OFFLINE_DEVICES, offlineDevices);
            result.put(MqttConstants.Monitoring.StatusFields.CONFIG_COUNT, configList.size());
            
            return result;
        } catch (Exception e) {
            log.error("获取公司MQTT设备状态汇总失败，companyId: {}, error: {}", companyId, e.getMessage(), e);
            // 返回空的结果Map而不是null
            Map<String, Object> emptyResult = new HashMap<>();
            emptyResult.put(MqttConstants.Monitoring.StatusFields.TOTAL_DEVICES, 0);
            emptyResult.put(MqttConstants.Monitoring.StatusFields.ONLINE_DEVICES, 0);
            emptyResult.put(MqttConstants.Monitoring.StatusFields.OFFLINE_DEVICES, 0);
            emptyResult.put(MqttConstants.Monitoring.StatusFields.CONFIG_COUNT, 0);
            return emptyResult;
        }
    }
    
    /**
     * 调用EMQX HTTP API获取设备状态
     *
     * @param config MQTT配置对象
     * @return 设备状态信息
     */
    private MqttDeviceStatusVo getEmqxDeviceStatus(MqttBrokerConfig config) {
        String responseBody = MqttApiUtil.executeEmqxApiGetRequest(config, MqttConstants.ApiEndpoints.STATS_ENDPOINT);
        if (responseBody == null) {
            return createEmptyStatus(config);
        }

        try {
            // EMQX v5 /stats API返回的是一个JSON数组，包含每个节点的信息
            JSONArray nodesStats = JSONUtil.parseArray(responseBody);
            int totalConnections = 0;
            int totalSessions = 0;

            for (Object nodeStatObj : nodesStats) {
                if (nodeStatObj instanceof JSONObject) {
                    JSONObject nodeStat = (JSONObject) nodeStatObj;
                    // 直接从JSONObject获取值，不再使用会错误分割带点号key的getIntValue方法
                    totalConnections += nodeStat.getInt(MqttConstants.ApiResponseFields.CONNECTIONS_COUNT, 0);
                    totalSessions += nodeStat.getInt(MqttConstants.ApiResponseFields.SESSIONS_COUNT, 0);
                }
            }

            MqttDeviceStatusVo status = new MqttDeviceStatusVo();
            status.setConfigId(config.getId());
            status.setConfigName(config.getName());
            status.setTotalDevices(totalSessions); // 总会话数代表总设备数
            status.setOnlineDevices(totalConnections); // 当前连接数代表在线设备数
            status.setOfflineDevices(totalSessions - totalConnections);
            return status;
        } catch (Exception e) {
            log.error("解析EMQX API响应失败: {}", e.getMessage(), e);
        }
        
        return createEmptyStatus(config);
    }
    
    /**
     * 创建空的状态对象
     *
     * @param config MQTT配置对象
     * @return 空的设备状态信息
     */
    private MqttDeviceStatusVo createEmptyStatus(MqttBrokerConfig config) {
        MqttDeviceStatusVo status = new MqttDeviceStatusVo();
        if (config != null) {
            status.setConfigId(config.getId());
            status.setConfigName(config.getName());
        } else {
            status.setConfigId(0L);
            status.setConfigName("未知配置");
        }
        status.setTotalDevices(0);
        status.setOnlineDevices(0);
        status.setOfflineDevices(0);
        return status;
    }
} 